﻿#include "mainwindow.h"
#include "logindlg.h"
#include "execsqldlg.h"
#ifdef __WIN__
#include "winsock.h"
#include "mysql.h"
#else
#include <mysql/mysql.h>
#endif // _WIN

#include <QMessageBox>
#include <QIcon>
#include <QMdiSubWindow>
#include <QStandardItem>
#include <QTableView>
#include <QTreeWidget>
#include <QTreeWidgetItem>
//#pragma  execution_character_set("utf-8")
//有时候用这个好使  如果不是utf编码 好像用下面这个好使
//#define  TR(text)     QString::fromUtf8(text)       
#define TR(text)      QString::fromLocal8Bit(text) 


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent) ,m_isLogin(false)
{
   this->CreateAction();
   this->CreatMenu();
   this->CreateDockWindow();
   this->CreateStatusBar();

   this->setWindowTitle(TR("无线管理系统"));
   this->SetBackGround();
   //添加中央控件
   m_centerArea = new QMdiArea(this);
   setCentralWidget(m_centerArea);  //设置中央控件为mdiArea
   m_centerArea->setBackground(Qt::NoBrush);
 
   //用CSS的格式来设置背景
   m_centerArea->setStyleSheet("background-image: url(bg.png)");
}

MainWindow::~MainWindow()
{

}


void MainWindow::CreatMenu() 
{
	m_menu = this->menuBar()->addMenu(TR("登录"));
	m_menu->addAction(m_actLogIn);
	m_menu->addAction(m_actLogOut);
	//给登录菜单加一个分隔符
	m_menu->addSeparator();
	m_menu->addAction(m_actExit);

	m_menuData = this->menuBar()->addMenu(TR("数据"));
	m_menuData->addAction(m_actData);
	m_menuData->addAction(m_actSql);

	m_menuWindow = this->menuBar()->addMenu(TR("窗口"));
	m_menuWindow->addAction(m_actFoldWindow);
	m_menuWindow->addAction(m_actParaWindow);

	m_menuHelp = this->menuBar()->addMenu(TR("帮助"));
	m_menuHelp->addAction(m_actAbout);
}

void MainWindow::CreateAction()
{
	m_actLogIn =new QAction(TR("登录"), this);
	m_actLogIn->setShortcut(TR("Ctrl+L"));	 
	m_actLogIn->setIcon(QIcon(TR("1.png")));

	m_actLogOut = new QAction(TR("注销"), this);
	m_actLogOut->setShortcut(TR("Ctrl+U"));

	m_actExit = new QAction(TR("关闭"), this);
	m_actExit->setShortcut(TR("Ctrl+E"));

	m_actData = new QAction(TR("解析数据"), this);
	m_actSql  = new QAction(TR("执行SQL语句"), this);

	m_actAbout =new QAction(TR("关于"), this);

	m_actFoldWindow = new QAction(TR("层叠窗口"), this);
	m_actParaWindow = new QAction(TR("并列窗口"), this);

	connect(m_actLogIn, SIGNAL(triggered()), this, SLOT(Slot_Login()));
	connect(m_actLogOut, SIGNAL(triggered()), this, SLOT(Slot_Logout()));
	connect(m_actExit, SIGNAL(triggered()), this, SLOT(Slot_exit()));
	connect(m_actAbout, SIGNAL(triggered()), this, SLOT(Slot_About()));
	connect(m_actData, SIGNAL(triggered()), this, SLOT(Slot_ShowSubWindow()));
	connect(m_actFoldWindow, SIGNAL(triggered()), this, SLOT(Slot_FoldWindow()));
	connect(m_actParaWindow, SIGNAL(triggered()), this, SLOT(Slot_ParaWindoe()));
	connect(m_actSql, SIGNAL(triggered()), this, SLOT(Slot_ExecSql()));
}

//创建树形控件 然后将其添加到浮动窗口中去
void MainWindow::CreateTreeWindow()
{
	//创建树形控件的一种方法 是先创建一个控件视图 
	//然后创建多个树形条款 
	m_treeWideget = new QTreeWidget();
	m_treeWideget->setHeaderLabel(TR("树形控件"));
	QList <QTreeWidgetItem *> rootList;
	//添加第一个节点
	QTreeWidgetItem *itemRoot1 = new QTreeWidgetItem;
	itemRoot1->setText(0, TR("根节点1"));
	rootList.append(itemRoot1);
	QTreeWidgetItem *itemRoot11 = new QTreeWidgetItem(itemRoot1, QStringList(QString(TR("节点1.1"))));
	itemRoot11->setIcon(0, QIcon("3.png"));
	QTreeWidgetItem *itemRoot12 = new QTreeWidgetItem(itemRoot1, QStringList(QString(TR("节点1.2"))));
	itemRoot12->setIcon(0, QIcon("3.png"));

	//添加第二节点
	QTreeWidgetItem *itemRoot2 = new QTreeWidgetItem;
	itemRoot2->setText(0, TR("根节点2"));
	rootList.append(itemRoot2);
	QTreeWidgetItem *itemRoot21 = new QTreeWidgetItem(itemRoot2, QStringList(QString(TR("节点2.1"))));
	itemRoot21->setIcon(0, QIcon("3.png"));
	QTreeWidgetItem *itemRoot22 = new QTreeWidgetItem(itemRoot2, QStringList(QString(TR("节点2.2"))));
	itemRoot22->setIcon(0, QIcon("3.png"));

	m_treeWideget->insertTopLevelItems(0, rootList);

	//连接信号
	connect(m_treeWideget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
		    this, SLOT(Slot_TreeViewProc(QTreeWidgetItem *, int)));

}

//创建一个浮动窗口
void MainWindow::CreateDockWindow()
{
	this->CreateTreeWindow();
	m_dockWindow = new QDockWidget(TR("浮动"), this, Qt::SubWindow);
	//设置悬浮窗容许悬浮的区域
	m_dockWindow->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
	//设置浮动窗口初始化时的位置
	this->addDockWidget(Qt::RightDockWidgetArea, m_dockWindow);
	m_dockWindow->setWidget(m_treeWideget);

}

//重载父类的关闭函数
void MainWindow::closeEvent(QCloseEvent * pEvent)
{
	QMessageBox::StandardButton button =	QMessageBox::question(this, QString(TR("退出")), QString(TR("确定退出吗?")), QMessageBox::Yes| QMessageBox::No);
	if(button == QMessageBox::Yes)
	{
		pEvent->accept();
	}
	else
	{
		pEvent->ignore();
	}
}

//
void MainWindow::SetBackGround()
{
	this->setWindowIcon(QIcon("3.png"));
	// 	this->setAutoFillBackground(true);
	// 	QPalette palette;
	// 	palette.setBrush(QPalette::Background, QBrush(QPixmap("bg.png")));
	// 	setPalette(palette);
}

void MainWindow::ShowItemView()
{
	//建立一个5行3列的model  将其加入中央控件中去
	QStandardItemModel *pModel = new QStandardItemModel(5, 4);
	//设置列的名称
	pModel->setHeaderData(0, Qt::Horizontal, TR("ID"));
	pModel->setHeaderData(1, Qt::Horizontal, TR("姓名"));
	pModel->setHeaderData(2, Qt::Horizontal, TR("性别"));
	pModel->setHeaderData(3, Qt::Horizontal, TR("年纪"));
	//设置每一个单元格的数据 pModel->index(0, 0, QModelIndex())是个固定用法
	pModel->setData(pModel->index(0, 0, QModelIndex()), TR("0001"));
	pModel->setData(pModel->index(0, 1, QModelIndex()), TR("张三"));
	pModel->setData(pModel->index(0, 2, QModelIndex()), TR("男"));
	pModel->setData(pModel->index(0, 3, QModelIndex()), TR("20"));
	QTableView *pTableView = new QTableView();
	pTableView->setAttribute(Qt::WA_DeleteOnClose);

// 	//添加右键菜单
	pTableView->addAction(m_actSql);
	pTableView->addAction(m_actParaWindow);
	pTableView->addAction(m_actFoldWindow);
	pTableView->addAction(m_actAbout);
	pTableView->setContextMenuPolicy(Qt::ActionsContextMenu);

	m_centerArea->addSubWindow(pTableView);
	pTableView->setModel(pModel);
	pTableView->show();
	//设置滚动条
	pTableView->adjustSize();
	pTableView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
	pTableView->setStyleSheet(TR("background-image: url(bg3.png)"));

}

void MainWindow::ShowSubWindow()
{
	QWidget *subWindow = new QWidget();
	//设置在关闭窗口的 时候自动释放内存
	subWindow->setAttribute(Qt::WA_DeleteOnClose);
	subWindow->setWindowIcon(QIcon(TR("2.png"))); // 
	//将subWindow加入中心控件区  使subWindow成为子窗口
	m_centerArea->addSubWindow(subWindow);
	subWindow->show();
	subWindow->setWindowTitle(TR("新窗口"));
	subWindow->setAutoFillBackground(true);
	subWindow->setStyleSheet(TR("background-image: url(bg2.png)"));
	//如果这个时候想设置子窗口的大小 要用下面这个方法
	m_centerArea->activeSubWindow()->resize(width()-100, height()-100);

	//设置窗口下方有一个水平的滚动条  当子窗口的范围超过父窗口的范围时 自动添加一个滚动条
	m_centerArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
	m_centerArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

//用于处理select语句
void MainWindow::SqlSelectProc()
{
	//首先获取表的字段
	vector<string> fieldName;
	fieldName = m_mysqlClient.GetfieldName();
	//字段的个数
	int fieldNum = m_mysqlClient.GetQueryFieldNum();

	//行数
	int rows = m_mysqlClient.GetQueryRowNum();

	//创建一个model 用于显示
	QStandardItemModel *pModel = new QStandardItemModel(rows, fieldNum, this);
	//设置标题
	for (int i = 0; i < fieldNum; i++)
	{
		pModel->setHeaderData(i, Qt::Horizontal, TR(fieldName[i].c_str()));
	}

	//开始填充数据
	int rowCnt = 0;
	while (true)
	{
		vector<string> rowInfo = m_mysqlClient.GetEachRowInfo();
		if(rowInfo.size() == 0)
		{
			break;
		}
		for (int i = 0; i < fieldNum; i++)
		{
			pModel->setData(pModel->index(rowCnt, i, QModelIndex()), tr(rowInfo[i].c_str()));
		}
		rowCnt++;
	}

	//释放查询的结果
	m_mysqlClient.FreeQueryResult();
	QTableView *pTableView = new QTableView();
	pTableView->setAttribute(Qt::WA_DeleteOnClose);
	pTableView->setModel(pModel);
	m_centerArea->addSubWindow(pTableView);

	pTableView->show();
	//设置窗口的大小到合适的位置  一定要先显示 然后再调用下面这句话 进行设置窗口打下 不然程序就崩溃了
	m_centerArea->activeSubWindow()->resize(width()-150, height()-100);
}


void MainWindow::CreateStatusBar()
{
	m_statusLab = new QLabel("ready");
	m_statusBar = statusBar();
	m_statusBar->addWidget(m_statusLab);
}

//------------------------------------SLOT-------------------------------------------
void MainWindow::Slot_Login()
{
	//首先判断用户是否已经登录
	if (m_isLogin)
	{
		if (m_mysqlClient.IsSqLConnect())
		{
			QMessageBox::information(this, TR("提示"), TR("用户已经登录"));
			return;
		}
		m_isLogin = false;
	}

	//在状态栏显示登录
	m_statusLab->setText("login");
	LoginDlg *dlg = new LoginDlg(this);
	dlg->setWindowTitle(TR("登录"));
	dlg->exec();  //产生模式对话框
	//开始连接数据库
	if (dlg->isLogin)
	{
		int ret = m_mysqlClient.SqlConnect(dlg->GetIp().toStdString(), dlg->GetUser().toStdString(),
															  dlg->GetPasswd().toStdString(), dlg->GetDataBaseName().toStdString() );
		if (ret != 1)
		{
			QString str("");
			str.append(m_mysqlClient.SQLErrINfo().c_str());
			QMessageBox::information(this, TR("连接失败"), str);
		}
		else
		{
			m_isLogin = true;
			//默认执行一下 set names utf8
			m_mysqlClient.SqlQuery("set names utf8");
			QMessageBox::information(this, TR("成功"), TR("连接成功"));
		}
	}
	delete dlg;
	m_statusLab->setText("ready");
}

void MainWindow::Slot_Logout()
{
	m_mysqlClient.SqlClose();
	m_isLogin = false;
	QMessageBox::information(this, TR("注销"), TR("注销成功"));
}

void MainWindow::Slot_exit()
{
	this->close();//调用这个函数 才会调用closeEvent函数
}

void MainWindow::Slot_About()
{
	QMessageBox::about(this, TR("关于"), TR("版本号:V1.0"));
}

void MainWindow::Slot_ShowSubWindow()
{
	this->ShowItemView();
}

void MainWindow::Slot_FoldWindow()
{
	m_centerArea->cascadeSubWindows();//层叠子窗口
}

void MainWindow::Slot_ParaWindoe()
{
	m_centerArea->tileSubWindows(); // 并列子窗口
}

void MainWindow::Slot_ExecSql()
{
	ExecSqlDlg *dlg = new ExecSqlDlg(this);
//	dlg->setAttribute(Qt::WA_DeleteOnClose);
	dlg->exec();
	if (dlg->GetSqlText().isEmpty())
	{
		delete dlg;
		return;
	}

	if (!m_isLogin)
	{
		QMessageBox::information(this, TR("错误"), TR("用户没有登录"));
		delete dlg;
		return;
	}
	
	//说明已经登录 判断是否还在连接
	if(!m_mysqlClient.IsSqLConnect())
	{
		m_isLogin = false;
		QMessageBox::information(this, TR("错误"), TR("连接到数据库断开, 请重新登录"));
		delete dlg;
		return;
	}

	if (0 == m_mysqlClient.SqlQuery(dlg->GetSqlText().toStdString()))
	{
		//在这里要判断一下执行的sql语句是否是select语句 如果是select语句 需要单独处理
		if (0 == dlg->GetSqlText().toStdString().compare(0, sizeof("select")-1, "select"))
		{
			m_mysqlClient.SaveQueryResult(NULL);
			SqlSelectProc();
		}
		else
		{
			QMessageBox::information(this, TR("成功"), TR("执行成功"));
		}
	}
	else
	{
		QString str("");
		str.append(m_mysqlClient.SQLErrINfo().c_str());
		QMessageBox::information(this, TR("执行失败"), str);
	}
	delete dlg;
}

//添加树形点击响应事件
void MainWindow::Slot_TreeViewProc(QTreeWidgetItem * item, int column)
{
	QTreeWidgetItem *rootItem = item->parent();
	if(rootItem == NULL)
	{
		//说明此处点击的根节点
		return;
	}
	int index = rootItem->indexOfChild(item);
	
	if (0 == column)
	{
		if (index == 0)
		{
			QMessageBox::information(this, "info", "select 0.1");
		}
		if (1 == index)
		{
			QMessageBox::information(this, "info", "select 0.2");
		}
	}

	if (1 == column)
	{
		if (index == 0)
		{
			QMessageBox::information(this, "info", "select 1.1");
		}
		if (1 == index)
		{
			QMessageBox::information(this, "info", "select 1.2");
		}
	}

	return;
}





